import React, { useRef, useEffect } from 'react';
import ReactDOM from 'react-dom';
import { Button, Row, Col, Tag, message } from 'antd';
import moment from 'moment';
import axios from 'axios';
import { convertBase64UrlToBlob } from '@/utils/file';
import './style.less';

const colors = ['#F0FFFF', '#6495ED', '#FF8C00', '#FFD700'];
class Board {
  // eslint-disable-next-line no-useless-constructor
  constructor(
    public el = document.querySelector<HTMLCanvasElement>('#blackboard')!,
    private app = el.getContext('2d')!,
    private height: number = el.height,
    private width: number = el.width, // eslint-disable-next-line no-empty-function
    private btnWrap: HTMLDivElement = document.createElement('div'),
    private bgColor = '#000',
    private penColor = '#fff',
  ) {
    this.initCanvas();
    this.bindEvent();
  }

  // 初始化画板操作
  private initCanvas() {
    this.app.fillStyle = this.bgColor;
    this.app.fillRect(0, 0, this.width, this.height);

    const that = this;
    ReactDOM.render(
      <>
        <Row gutter={24}>
          <Col>
            <Button type="primary" onClick={() => that.clear()}>
              清空黑板
            </Button>
          </Col>
          <Col>
            <Button type="primary" onClick={() => that.erase()}>
              橡皮
            </Button>
          </Col>
          <Col>
            <Button type="primary" onClick={() => that.setBgColor('skyblue')}>
              设置背景色
            </Button>
          </Col>
          <Col>
            <Button type="primary" onClick={() => that.getSnapshot()}>
              截图
            </Button>
          </Col>
          <Col>
            <Button type="primary" onClick={() => that.uploadSnapshot()}>
              上传至服务器
            </Button>
          </Col>
        </Row>
        <Row style={{ marginTop: 20 }}>
          {colors.map(c => (
            <Tag color={c} key={c} onClick={() => that.setPenColor(c)}>
              <span style={{ color: 'black' }}>{c}</span>
            </Tag>
          ))}
        </Row>
      </>,
      this.btnWrap,
    );
    this.el.insertAdjacentElement('afterend', this.btnWrap);
  }

  // 绑定画笔操作
  private bindEvent() {
    const callback = this.drawLine.bind(this);
    this.el.addEventListener('mousedown', () => {
      this.app.beginPath();
      this.app.strokeStyle = this.penColor;
      this.el.addEventListener('mousemove', callback);
    });
    // 只能绑到document，不然移到黑板外面会失效
    document.addEventListener('mouseup', () => {
      this.el.removeEventListener('mousemove', callback);
    });
  }

  // 画线
  private drawLine(event: MouseEvent) {
    this.app.lineTo(event.offsetX, event.offsetY);
    this.app.stroke();
  }

  // 清空
  private clear() {
    this.app.fillStyle = this.bgColor;
    this.app.fillRect(0, 0, this.el.width, this.el.height);
    return this;
  }

  // 橡皮
  private erase() {
    this.setPenColor(this.bgColor, 15);
  }

  // 截图
  private getSnapshot() {
    const base64 = this.el.toDataURL();
    const a = document.createElement('a');
    a.href = base64;
    a.download = `画布  ${moment().format('YYYY-MM-DD HH:mm:ss')}`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  }

  // 上传至服务器
  private uploadSnapshot() {
    const base64 = this.el.toDataURL('image/png');
    const blob = convertBase64UrlToBlob(base64);

    const fd = new FormData();
    fd.append('image', blob);
    fd.append('snapshot', `blackboard-${moment().format('MM-DD HH:mm:ss')}`);
    axios('/saveSnapshot', {
      method: 'POST',
      data: fd,
    }).then(res => {
      if (res.data.success) {
        message.success('上传成功～');
      }
    });
  }

  // 设置背景色
  private setBgColor(color: string) {
    this.bgColor = color;
    this.app.fillStyle = color;
    this.app.fillRect(0, 0, this.el.width, this.el.height);
    return this;
  }

  // 设置笔的颜色
  private setPenColor(color: string, width: number = 1) {
    this.app.lineWidth = width;
    this.penColor = color;
    this.app.strokeStyle = color;
    return this;
  }
}

export default function BlackBoard() {
  const ref = useRef<Board>();
  useEffect(() => {
    ref.current = new Board();
  }, []);
  return (
    <div className="blackboard-wrapper">
      <canvas id="blackboard" width="600" height="400" />
    </div>
  );
}
